/**
 * 
 */
package com.momosw.games.engine;

import java.util.LinkedList;
import java.util.List;

import com.momosw.games.engine.player.Player;
import com.momosw.games.engine.util.Utils;
import com.momosw.games.jericho.actions.DrawCardAction;
import com.momosw.games.jericho.actions.FeedSupplyAction;
import com.momosw.games.jericho.actions.PlayCardAction;

/**
 * 
 * <ul>
 * <li>Fetching the available actions for a given player.</li>
 * </ul>
 * 
 * <b>Project:</b> JerichoCardGame<br />
 * <b>Package:</b> com.momosw.games.engine<br />
 * <b>Class:</b> Turn.java<br />
 * <br />
 * <i>GSI 2011</i><br />
 *
 * @author Miguel Coronado (miguelcb84@gmail.com)
 * @version	Aug 16, 2011
 *
 */
public class Turn {

    /** The game */
    Game game;
    /** The current player */
    Player currentPlayer;
    /** The sequence for the turn */
    TurnSequence turnSequence;
    
    /**
     * Constructor. 
     * @param game
     * @param player
     */
    public Turn(Game game, Player player) {
        this.game = game;
        this.currentPlayer = player;
        setUpTurn(game.getConfig());
    }
    
    /**
     * SetUp the current turn. This usually includes building the TurnSequence
     * @param config
     */
    void setUpTurn (GameConfiguration config) {
        List<TurnSequenceNode> nodes = new LinkedList<TurnSequenceNode>();
        nodes.add( new TurnSequenceNode()
            .addAction(new PlayCardAction(game, currentPlayer), 1)
            .addAction(new FeedSupplyAction(game, currentPlayer), 1));
        nodes.add(new TurnSequenceNode()
            .addAction(new EndTurnAction(game, currentPlayer), 1));
        this.turnSequence = new TurnSequence(nodes);
    }

    /**
     * Start the turn
     */
    public void onStart() {
        Utils.notifyPlayers(game, currentPlayer, this.game.getBoard());
        currentPlayer.takeTurn(game, this);
        onEnd();
    }
    
    /**
     * <p>Executes this at the end of the turn</p>
     */
    private void onEnd() {
       this.execute(new DrawCardAction(this.game, this.currentPlayer), 
                    this.currentPlayer); 
    }

    /**
     * <p>Execute the action given</p>
     * @param action    Action
     * @param player    Player
     */
    public void execute(Action action, Player player) {
        action.execute();
    }

    /**
     * List the available actions. This depends of the player given 
     * and the state of the TurnSequence.
     * 
     * @param player
     * @return
     */
    public List<Action> availableActions(Player player) {
        return turnSequence.availableActions(player);
    }
    
    /**
     * 
     * @param action
     */
    public void doAction(Action action) {
        turnSequence.doAction(action);        
    }
    
}
